package dao;

import model.UsrType;
import util.*;

import java.math.BigInteger;
import java.sql.SQLException;
import java.util.List;

/**
 * 用户类型信息管理模块DAO
 * author 兰彦真
 */
public class UsrTypeManager implements UsrTypesManagement {

    /**
     * 新增一个用户类型
     * @param utyp 包含新用户类型信息的对象
     * @return 新类型在数据库中的id
     */
    @Override
    public Long insertOne(UsrType utyp) {
        if(utyp == null  ||  Common.isStringEmpty(utyp.getUtyp_name())  ||  Common.isStringEmpty(utyp.getUtyp_descript())) return null;
        try {
            //从连接池获取一个数据库连接
            JDBCConnection conn = JDBCFactory.takeJDBC();
            //执行插入，得到主键id
            Long gKey = ((BigInteger) conn.updateForGeneratedKey("insert into t_usrtypes values(null,?,?)", utyp.getUtyp_name(), utyp.getUtyp_descript())).longValue();
            //归还连接
            JDBCFactory.returnBack(conn);
            //返回主键id
            return gKey;
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return null;
        }
    }

    /**
     * 更改一个用户类型的信息
     * @param utyp 所要更改的用户类型，必须指定一个 id 或 tag，其余可以留null
     * @param desti 目的修改数据，不修改的字段留 null，id 不可修改，将被忽略
     * @return 修改成功返回true，否则返回false
     */
    @Override
    public boolean updateOne(UsrType utyp, UsrType desti) {
        //判空
        if(utyp == null  ||  desti == null  ||  utyp.getUtyp_id() == null && Common.isStringEmpty(utyp.getUtyp_name())
                || Common.isStringEmpty(desti.getUtyp_name()) && Common.isStringEmpty(desti.getUtyp_descript())
        ) return false;

        boolean firstArg = true;

        //sql查询语句母体
        String sql = "update t_usrtypes set";

        String sql_condition = null;

        //sql语句更新字段参数拼接字符串
        StringBuilder sql_args = new StringBuilder();

        //sql操作更新的实参列表
        ArgsList<Object> args = new ArgsList<>();

        //若设定了对 tag 的修改
        if(!Common.isStringEmpty(desti.getUtyp_name())) {
            //拼接新的 sql 更新字段
            if(!firstArg) sql_args.append(',');
            sql_args.append(" utyp_name = ?");
            //添加实参到列表
            args.add(desti.getUtyp_name());
            firstArg = false;
        }

        //若设定了对 descript 的修改
        if(!Common.isStringEmpty(desti.getUtyp_descript())) {
            if(!firstArg) sql_args.append(',');
            sql_args.append(" utyp_descript = ?");
            args.add(desti.getUtyp_descript());
            firstArg = false;
        }

        //若不知道类别的id，按类别名称获取id
        if(utyp.getUtyp_id() != null) {
            sql_condition = " where utyp_id = ?";
            args.add(utyp.getUtyp_id());
        } else {
            sql_condition = " where utyp_name = ?";
            args.add(utyp.getUtyp_name());
        }
        try {
            //更新记录
            JDBCConnection conn = JDBCFactory.takeJDBC();
            int count = conn.update(args, "update t_usrtypes set" + sql_args.toString() + sql_condition);
            JDBCFactory.returnBack(conn);

            return count == 1;
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return false;
        }
    }

    /**
     * 删除用户类型 (会删除用户的目的类型属性，但会保留该用户和其它类型属性)
     * @param utype 要删除的类型
     * @return 受影响的用户个数
     */
    @Override
    public int deleteOne(UsrType utype) {
        //判空
        if(utype == null  ||  utype.getUtyp_id() == null && Common.isStringEmpty(utype.getUtyp_name())) return 0;
        Long gtypID = null;

        try {
            //从连接池获取一个数据库连接
            JDBCConnection conn = JDBCFactory.takeJDBC();
            //开启事务
            conn.start();

            //若不知道类别的id，按类别名称获取id
            if ((gtypID = utype.getUtyp_id()) == null) {
                List<Object[]> tmp = conn.query("select utyp_id from t_usrtypes where utyp_name = ?", utype.getUtyp_name());

                //未找到该名称的消息类型
                if (tmp.size() == 0) {
                    //回滚事务
                    conn.rollback();
                    //归还连接
                    JDBCFactory.returnBack(conn);
                    return 0;
                }
                gtypID = (Long) JDBCConnection.getGeneratedKey(tmp);
            }

            //删除用户与该类型的关联
            int count = conn.update("delete from t_usertype where utyp_id = ?", gtypID);
            //删除该类型
            conn.update("delete from t_usrtypes where utyp_id = ?", gtypID);

            //提交事务
            conn.commit();
            //归还连接
            JDBCFactory.returnBack(conn);
            return count;
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return 0;
        }
    }

    /**
     * 包装并返回查询到的对象的列表
     * @param list 包含 SQL 行查询结果的列表，Object[]中每一项都是一列的值
     * @return 返回包装好的对象列表
     */
    private static List<UsrType> getResultList(List<Object[]> list)
    {
        List<UsrType> result = new ResultList<>();

        for(Object[] row : list)result.add(new UsrType(row));

        return result;
    }

    @Override
    public List<UsrType> queryAll(int pageSize, int page) {
        try {
            JDBCConnection conn = JDBCFactory.takeJDBC();
            List<Object[]> list = conn.query("select * from t_usrtypes limit ?, ?", (page - 1) * pageSize, pageSize);
            JDBCFactory.returnBack(conn);
            if (list.isEmpty()) return null;
            return getResultList(list);
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return null;
        }
    }

    @Override
    public UsrType queryByName(String name) {
        try {
            JDBCConnection conn = JDBCFactory.takeJDBC();
            List<Object[]> list = conn.query("select * from t_usrtypes where utyp_name = ?", name);
            JDBCFactory.returnBack(conn);
            if (list.isEmpty()) return null;
            return getResultList(list).get(0);
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return null;
        }
    }

    @Override
    public UsrType queryByID(Long id) {
        try {
            JDBCConnection conn = JDBCFactory.takeJDBC();
            List<Object[]> list = conn.query("select * from t_usrtypes where utyp_id = ?", id);
            JDBCFactory.returnBack(conn);
            if (list.isEmpty()) return null;
            return getResultList(list).get(0);
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return null;
        }
    }

    /**
     * 在一个事务内（避免死锁）获取或创建一个用户类型
     * @param name 类型名，不可为null
     * @param descript 如果类型不存在，创建类型时指定的类型描述，可为null
     * @return 类型的id，失败返回null
     */
    Long getUserType(JDBCConnection conn, String name, String descript)
    {
        try {
            List<Object[]> list = conn.query("select * from t_usrtypes where utyp_name = ?", name);
            if (list.isEmpty()) {
                return ((BigInteger) conn.updateForGeneratedKey("insert into t_usrtypes values(null,?,?)", name, descript)).longValue();
            } else return getResultList(list).get(0).getUtyp_id();
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return null;
        }
    }
}

